/**
 * Notes:  TS framework
 * Created by Visual Studio Code.
 * Author: TS
 * Date: 2019/12/04
 * Time: 10:40
 */
var ts = {
    ModuleServer: 'TS/util/',//组件地址
    cryptCode: '92644664',//加密秘钥
    /**
     * 使用组件
     * @param {*} moduleName 
     * @param {*} callback 
     */
    use: function (moduleName, callback) {
        let lastScript = null;
        try {
            if (typeof moduleName == 'string') {
                lastScript = ts.import(moduleName);
            } else {
                for (let index in moduleName) {
                    lastScript = ts.import(moduleName[index]);
                }
            }
            if (typeof callback == "function") {
                if (lastScript != null) {
                    lastScript.onload = function () {
                        lastScript.onload = null;
                        callback();

                    }
                } else {
                    callback();
                }
            }
        } catch (e) {
            ts.log(e);
        }
    },
    /**
     * 导入组件
     * @param {*} moduleName 组件名称
     */
    import: function (moduleName) {
        let moduleElement = document.createElement("script");//创建新的script节点
        let moduleUrl = ts.ModuleServer + moduleName + ".js";
        let checkHas = document.querySelector('script[src="' + moduleUrl + '"]');
        if (!checkHas) {
            moduleElement.setAttribute("type", "text/javascript");
            moduleElement.setAttribute("src", moduleUrl);
            try {
                document.body.appendChild(moduleElement);
                return moduleElement;
            } catch (e) {
                ts.log(e);
            }
        }
        return null;
    },
    /**
     * 日志输出
     * @param {*} msg 日志内容
     */
    log: function (msg) {
        let header = '------' + ts.Date.getDate("yyyy-MM-dd h:m:s") + '------\n';
        console.log(header + msg);
    },
    /**
     * 加密
     * @param {*} data 加密数据
     * @param {可选} key 加密秘钥
     */
    encrypt: function (data, key) {
        if (data == null) return null;
        if (key == null) key = ts.cryptCode;
        let res = ts.crypt(data, key);
        return ts.Base64.encode(res);
    },
    /**
     * 解密
     * @param {*} data 解密密文
     * @param {可选} key 解密秘钥
     */
    decrypt: function (data, key) {
        if (data == null) return null;
        data = ts.Base64.decode(data);
        if (key == null) key = ts.cryptCode;
        return ts.crypt(data, key);
    },
    /**
     * 加密主体
     * @param {*} data 加密明文
     * @param {可选} key 加密秘钥
     */
    crypt: function (data, key) {
        var seq = Array(256);
        var das = Array(data.length);
        for (var i = 0; i < 256; i++) {
            seq[i] = i;
            var j = (j + seq[i] + key.charCodeAt(i % key.length)) % 256;
            var temp = seq[i];
            seq[i] = seq[j];
            seq[j] = temp;
        }
        for (var i = 0; i < data.length; i++) {
            das[i] = data.charCodeAt(i)
        }
        for (var x = 0; x < das.length; x++) {
            var i = (i + 1) % 256;
            var j = (j + seq[i]) % 256;
            var temp = seq[i];
            seq[i] = seq[j];
            seq[j] = temp;
            var k = (seq[i] + (seq[j] % 256)) % 256;
            das[x] = String.fromCharCode(das[x] ^ seq[k]);
        }
        return das.join('');
    },
    /**
     * Base64加密
     */
    Base64: {
        _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
        encode: function (e) {
            var t = "";
            var n, r, i, s, o, u, a;
            var f = 0;
            e = ts.Base64._utf8_encode(e);
            while (f < e.length) {
                n = e.charCodeAt(f++);
                r = e.charCodeAt(f++);
                i = e.charCodeAt(f++);
                s = n >> 2;
                o = (n & 3) << 4 | r >> 4;
                u = (r & 15) << 2 | i >> 6;
                a = i & 63;
                if (isNaN(r)) {
                    u = a = 64
                } else if (isNaN(i)) {
                    a = 64
                }
                t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
            }
            return t
        },
        decode: function (e) {
            var t = "";
            var n, r, i;
            var s, o, u, a;
            var f = 0;
            e = e.replace(/[^A-Za-z0-9+/=]/g, "");
            while (f < e.length) {
                s = this._keyStr.indexOf(e.charAt(f++));
                o = this._keyStr.indexOf(e.charAt(f++));
                u = this._keyStr.indexOf(e.charAt(f++));
                a = this._keyStr.indexOf(e.charAt(f++));
                n = s << 2 | o >> 4;
                r = (o & 15) << 4 | u >> 2;
                i = (u & 3) << 6 | a;
                t = t + String.fromCharCode(n);
                if (u != 64) {
                    t = t + String.fromCharCode(r)
                }
                if (a != 64) {
                    t = t + String.fromCharCode(i)
                }
            }
            t = ts.Base64._utf8_decode(t);
            return t
        },
        _utf8_encode: function (e) {
            e = e.replace(/rn/g, "n");
            var t = "";
            for (var n = 0; n < e.length; n++) {
                var r = e.charCodeAt(n);
                if (r < 128) {
                    t += String.fromCharCode(r)
                } else if (r > 127 && r < 2048) {
                    t += String.fromCharCode(r >> 6 | 192);
                    t += String.fromCharCode(r & 63 | 128)
                } else {
                    t += String.fromCharCode(r >> 12 | 224);
                    t += String.fromCharCode(r >> 6 & 63 | 128);
                    t += String.fromCharCode(r & 63 | 128)
                }
            }
            return t
        },
        _utf8_decode: function (e) {
            var t = "";
            var n = 0;
            var r = c1 = c2 = 0;
            while (n < e.length) {
                r = e.charCodeAt(n);
                if (r < 128) {
                    t += String.fromCharCode(r);
                    n++
                } else if (r > 191 && r < 224) {
                    c2 = e.charCodeAt(n + 1);
                    t += String.fromCharCode((r & 31) << 6 | c2 & 63);
                    n += 2
                } else {
                    c2 = e.charCodeAt(n + 1);
                    c3 = e.charCodeAt(n + 2);
                    t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
                    n += 3
                }
            }
            return t
        }
    },
    /**
     * 获取url参数
     * @param {*} name 参数名称
     */
    getQuery: function (name) {
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        var r = window.location.search.substr(1).match(reg);
        if (r != null) return unescape(r[2]); return null;
    },
    /**
     * 设置、更新url参数，如参数存在则更新，如不存在则添加
     * @param {*} key 参数名称
     * @param {*} value 参数值
     */
    setQuery: function (key, value) {
        var uri = window.location.href;

        if (!value) {
            return uri;
        }
        var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
        var separator = uri.indexOf('?') !== -1 ? "&" : "?";
        var state = {
            title: document.title,
            url: document.location.href,
            otherkey: null
        };

        if (uri.match(re)) {
            history.replaceState(state, document.title, uri.replace(re, '$1' + key + "=" + value + '$2'));
        }
        else {
            history.replaceState(state, document.title, uri + separator + key + "=" + value);
        }
    },
    Date: {
        /**
         * 获取时间
         * @param {可选} format 时间格式，默认为yyyy-M-d h:m:s
         */
        getDate: function (format = "yyyy-M-d h:m:s") {
            let nowDate = new Date();
            var weeks = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
            var minute = nowDate.getMinutes(), second = nowDate.getSeconds();
            minute < 9 && (minute = "0" + minute.toString());
            second < 9 && (second = "0" + second.toString());
            var date = {
                "y+": nowDate.getFullYear(),                       //年份
                "M+": nowDate.getMonth() + 1,                      //月份   
                "d+": nowDate.getDate(),                           //日 
                "w+": weeks[nowDate.getDay()],                    //星期  
                "h+": nowDate.getHours(),                          //小时   
                "m+": minute,                                   //分   
                "s+": second,                                   //秒   
                "q+": Math.floor((nowDate.getMonth() + 3) / 3),    //季度   
                "S": nowDate.getMilliseconds()                     //毫秒   
            };
            for (var item in date) {
                if (new RegExp("(" + item + ")").test(format)) {
                    format = format.replace(RegExp.$1, date[item]);
                }
            }
            return format;
        }
    },
    /**
     * 根据身份证获取生日，yyyy-MM-dd格式
     * @param {*} cardId 
     */
    getBirthdatByIdNo: function (cardId) {
        var tmpStr = "";
        cardId = cardId.replace(/^\s+|\s+$/g, "");
        if (cardId.length == 15) {
            tmpStr = cardId.substring(6, 12);
            tmpStr = "19" + tmpStr;
            tmpStr = tmpStr.substring(0, 4) + "-" + tmpStr.substring(4, 6) + "-" + tmpStr.substring(6)
            return tmpStr;
        } else {
            tmpStr = cardId.substring(6, 14);
            tmpStr = tmpStr.substring(0, 4) + "-" + tmpStr.substring(4, 6) + "-" + tmpStr.substring(6)
            return tmpStr;
        }
    },
    /**
     * 根据生日或者身份证计算星座
     * @param {*} value 生日，或者身份证
     * @param {*} sp 生日格式
     */
    getConstellation: function (value, sp = '-') {
        if (!value || value == "") return;
        if (value.length > 15) value = ts.getBirthdatByIdNo(value), sp = '-';
        birthday = value.split(sp);
        let month = birthday[1], day = birthday[2];
        let constellation = null;
        const constellation_name = ['水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座', '狮子座', '处女座', '天秤座', '天蝎座', '射手座', '摩羯座'];
        day <= 22 ? (1 !== parseInt(month) ? constellation = constellation_name[month - 2] : constellation = constellation_name[11]) : constellation = constellation_name[month - 1];
        return constellation;
    },
    /**
     * 根据生日或者身份证计算生肖
     * @param {*} value 生日，或者身份证
     * @param {*} sp 生日格式
     */
    getAnimals: function (value, sp = '-') {
        if (!value || value == "") return;
        if (value.length > 15) value = ts.getBirthdatByIdNo(value), sp = '-';
        birthday = value.split(sp);
        let year = birthday[0], month = birthday[1], day = birthday[2];
        const animalsArray = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
        //生肖算法为：（年-1900）求模12
        let key = (year - 1900) % 12;
        return animalsArray[key];
    },
    /**
     * 根据生日或者身份证计算年龄
     * @param {*} value 生日，或者身份证
     * @param {*} sp 生日格式
     */
    getAge: function (value, sp = '-') {
        if (!value || value == "") return;
        if (value.length > 15) value = ts.getBirthdatByIdNo(value), sp = '-';
        var age,
            birthdayArr = value.split(sp),
            birthYear = birthdayArr[0],
            birthMonth = birthdayArr[1],
            birthDay = birthdayArr[2],
            d = new Date(),
            nowYear = d.getFullYear(),
            nowMonth = d.getMonth() + 1,
            nowDay = d.getDate();
        if (nowYear == birthYear) {
            age = 0; //同年 则为0岁
        } else {
            var ageDiff = nowYear - birthYear; //年之差
            if (ageDiff > 0) {
                if (nowMonth == birthMonth) {
                    var dayDiff = nowDay - birthDay; //日之差
                    if (dayDiff < 0) {
                        age = ageDiff - 1;
                    } else {
                        age = ageDiff;
                    }
                } else {
                    var monthDiff = nowMonth - birthMonth; //月之差
                    if (monthDiff < 0) {
                        age = ageDiff - 1;
                    } else {
                        age = ageDiff;
                    }
                }
            } else {
                age = -1; //返回-1 表示出生日期输入错误 晚于今天
            }
        }
        return age; //返回周岁年龄
    },
    /**
     * 设置model值
     * @param {*} response 
     */
    setModel: function (response) {
        if (response.data == null) return false;
        var modelAttr = response.attr || 'model',
            fatherElem = response.elem || 'body',
            data = response.data;
        try {
            if (response.easyui) ts.use('easyui-model');
            document.querySelectorAll(fatherElem + ' [' + modelAttr + ']').forEach(element => {
                var key = element.getAttribute(modelAttr), 
                nodeName = element.tagName,
                className = element.getAttribute('class');
                if (className != null &&className.indexOf('easyui') != -1) {
                    ts.Easyui.setEasyuiValue(fatherElem + ' [' + modelAttr + '="' + key + '"]', data[key]);
                } else {

                    if (nodeName == 'INPUT') {
                        if (data[key] != null) element.setAttribute('value', data[key]);
                    } else if (nodeName == 'IMG') {
                        if (data[key] != null) element.setAttribute('src', data[key]);
                    } else {
                        if (data[key] != null) element.innerText = data[key];
                    }
                }
            });
        } catch (e) {
            ts.log(e);
        }
    },
    /**
     * 获取model值
     * @param {*} response 
     */
    getModel: function (response = {}) {
        var modelAttr = response.attr || 'model'
            , fatherElem = response.elem || 'body';
        var data = {};
        try {
            if (response.easyui) ts.use('easyui-model');
            document.querySelectorAll(fatherElem + ' [' + modelAttr + ']').forEach(element => {
                var key = element.getAttribute(modelAttr), nodeName = element.tagName,
                className = element.getAttribute('class');
                if (className != null && className.indexOf('easyui') != -1) {

                    data[key] = ts.Easyui.getEasyuiValue(fatherElem + ' [' + modelAttr + '="' + key + '"]');

                } else {
                    if (nodeName == 'INPUT' || nodeName == 'SELECT' || nodeName == 'TEXTAREA') {
                        if (element.type == "radio") {
                            data[key] = document.querySelector(fatherElem + ' [' + modelAttr + ']:checked').value;
                        } else {
                            data[key] = element.value;
                        }
                    } else if (nodeName == 'IMG') {
                        data[key] = element.getAttribute('src');
                    } else {
                        data[key] = element.innerText;
                    }
                }
            });
        } catch (e) {
            ts.log(e);
        }
        return data;
    }
};
ts.Easyui = {};